package com.qf.qfusermanager.filter;

import com.alibaba.fastjson.JSON;
import com.qf.common.bean.R;
import com.qf.common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;

public class JwtVerifyFilter extends BasicAuthenticationFilter {

    public JwtVerifyFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("-------------------");

        //黑名单处理

        //获取token头
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)){
            token = request.getParameter("token");
        }

        if (StringUtils.isEmpty(token) || "null".equals(token)){
            //没带或者不需要
            chain.doFilter(request,response);
            return;
        }

        //验证token的合法性
        try {
            Claims claims = JwtUtil.parseJWT(token);
            //向上下文中存入合法信息
            saveContext(claims);
        }catch (ExpiredJwtException expire){

            //有效时间
            long time = expire.getClaims().getExpiration().getTime();
            long permitTime = System.currentTimeMillis()+1000*60*30;

            if (time <= permitTime){
                //允许复活
                String newJwt = JwtUtil.createJWT(UUID.randomUUID().toString().replaceAll("-", ""),
                        expire.getClaims().getSubject(),
                        null
                );

                //向上下文中存入认证信息
                saveContext(expire.getClaims());

                //要将新的jwt返回到页面端
                response.setHeader("refresh_token",newJwt);

            }else{
                expire.printStackTrace();
                //过期
                R r = R.fail(R.Code.UNAUTHENTICATED,"尚未登录");
                String json = JSON.toJSONString(r);

                response.setContentType("application/json;charset=utf-8");
                response.getWriter().write(json);
                return;
            }

        } catch (Exception e) {
            e.printStackTrace();

            R r = R.fail(R.Code.UNAUTHENTICATED,"尚未登录");
            String json = JSON.toJSONString(r);

            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(json);
            return;
        }

        chain.doFilter(request,response);
    }

    private void saveContext(Claims claims) {
        String id = claims.getSubject();

        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(id,null, AuthorityUtils.createAuthorityList("default"));
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
}
